import { ref } from 'vue'
import store from '@/store'
import { ElMessage } from 'element-plus'
import { BaseRequestMethod } from '@/api/request/types'
import SearchPanel from '@/components/search-panel/index.vue'
import { FormItem as SearchFormItem } from '@/components/search-panel/types'
import { LayoutRow } from '@/components/mm-dialog/type'
import { PaginationData } from '@/components/data-table/types'
import MmDialog from '@/components/mm-dialog/index.vue'
import { usePermission } from './use-permission'
import { copy } from '@/utils/common'

/**
 * 页面配置选项
 * @member initStoreModule vuex 模块名，用于调用对应模块的初始化函数来请求页面相关预加载的数据，留空则不调用
 * @member searchFormItems 搜索表单项，用于动态生成表单
 * @member dialogFromItem 窗口表单项，用于动态生成表单
 * @member dataParams 额外传递的参数(请求、创建数据时指定某些关联ID)
 * @member queryPagination 分页参数
 */
export interface PageOptions {
  initStoreModule?: string
  searchFormItems?: SearchFormItem[]
  dialogLayoutRows?: LayoutRow[]
  checkPermissions?: string[]
  isCheckQueryPermission?: boolean
  dataParams?: Record<string, unknown>
  queryPagination?: PaginationData
}

/**
 * 页面相关逻辑
 * @param api 与页面对应的 api
 * @param pageOptions 页面配置选项
 */
export function usePage(api: BaseRequestMethod, pageOptions?: PageOptions) {
  const searchFormRawData: any = {}
  pageOptions?.searchFormItems?.forEach((item) => {
    searchFormRawData[item.field] = ''
  })
  const searchForm = ref(searchFormRawData)
  const searchPanelRef = ref<InstanceType<typeof SearchPanel>>()

  const tableDataList = ref<any[]>([])
  const tableDataCount = ref(0)
  const tablePagination = ref<PaginationData>({ currentPage: 1, pageSize: 10, ...pageOptions?.queryPagination })

  const mainDialogRef = ref<InstanceType<typeof MmDialog>>()
  const mainDialogDefaultData = ref<any>({})
  const mainDialogValidateRules = ref<any>({})
  pageOptions?.dialogLayoutRows?.forEach((row) => {
    row.formItems.forEach((item) => {
      mainDialogValidateRules.value[item.prop] = item.rules
    })
  })

  const pagePermissions: any = {}
  pageOptions?.checkPermissions?.forEach((item) => {
    pagePermissions[item] = usePermission(item)
  })

  // 公共 api 方法 - 查询列表
  const getDataList = (
    page: number = tablePagination.value.currentPage,
    limit: number = tablePagination.value.pageSize
  ) => {
    // 检查权限
    if (pageOptions?.isCheckQueryPermission !== false && !pagePermissions['view']) {
      ElMessage.error('权限不足')
      return
    }
    api
      .getDataList({ ...searchFormRawData, ...pageOptions?.dataParams, page, limit })
      .then((res) => {
        // 保存数据
        tableDataList.value = res.data.list
        tableDataCount.value = res.data.total
        // 保存分页，让分页组件 El-Pagination 正确显示页码
        tablePagination.value.currentPage = page
        tablePagination.value.pageSize = limit
      })
      .catch((error) => {
        ElMessage.error(error)
      })
  }

  // 公共 api 方法 - 创建
  const createData = (data: any) => {
    api
      .createData({ ...data, ...pageOptions?.dataParams })
      .then((res) => {
        ElMessage.success('添加成功')
        mainDialogRef.value?.visible(false)
        // 刷新表格数据
        getDataList()
      })
      .catch((error) => {
        ElMessage.error(error)
      })
  }

  // 公共 api 方法 - 修改
  const updateData = (id: number, data: any) => {
    api
      .updateData(id, data)
      .then((res) => {
        ElMessage.success('修改成功')
        mainDialogRef.value?.visible(false)
        // 刷新表格数据
        getDataList()
      })
      .catch((error) => {
        ElMessage.error(error)
      })
  }

  // 公共 api 方法 - 删除
  const deleteData = (id: number) => {
    api
      .deleteData(id)
      .then((res) => {
        ElMessage.success('删除成功')
        // 刷新表格数据
        getDataList()
      })
      .catch((error) => {
        ElMessage.error(error)
      })
  }

  // 首次请求表格数据
  getDataList()

  // 请求页面需要预加载的额外数据
  if (pageOptions?.initStoreModule) {
    store.dispatch(pageOptions.initStoreModule + '/init')
  }

  // 搜索 - 查询事件
  const handleQuery = () => {
    // 把查询条件保存起来，查询使用保存的条件
    // 对查询表单的修改在没有点击查询按钮之前，不会影响查询结果
    copy(searchFormRawData, searchForm.value)
    // 查询时，从第一页开始
    getDataList(1)
  }

  // 搜索 - 重置事件
  const handleReset = () => {
    searchPanelRef.value?.resetFields()
  }

  // 表格 - 分页事件：currentChange
  const handleCurrentChange = (currentPage: number) => {
    getDataList(currentPage)
  }

  // 表格 - 分页事件：sizeChange
  const handleSizeChange = (size: number) => {
    // 切换每页数量时，从第一页开始
    getDataList(1, size)
  }

  // 表格 - 分页事件：sizeChange
  const handlePageChange = (size: number) => {
    // 切换每页数量时，从第一页开始
    getDataList(1, size)
  }

  return {
    searchForm,
    searchPanelRef,
    tableDataList,
    tableDataCount,
    tablePagination,
    handleQuery,
    handleReset,
    handleCurrentChange,
    handleSizeChange,
    handlePageChange,
    mainDialogRef,
    mainDialogDefaultData,
    mainDialogValidateRules,
    pagePermissions,
    getDataList,
    createData,
    updateData,
    deleteData
  }
}
